package com.ly.mp.busicen.rule.flow.filter.plugin;

import static com.ly.mp.busicen.rule.XruleStrUtils.splitXKH;

import java.lang.reflect.InvocationTargetException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.ly.mp.busicen.common.context.BusicenException;
import com.ly.mp.busicen.rule.flow.FlowSpelUtil;
import com.ly.mp.busicen.rule.flow.action.ActionResult;
import com.ly.mp.busicen.rule.flow.action.IActionResult.Signal;
import com.ly.mp.busicen.rule.flow.filter.FlowFilterBase;
import com.ly.mp.busicen.rule.flow.filter.FlowInvocation;
import com.ly.mp.busicen.rule.flow.filter.FlowResult;
import com.ly.mp.busicen.rule.flow.filter.FlowResultImpl;

@Component
public class SpelPostFilter extends FlowFilterBase {

	Logger log = LoggerFactory.getLogger(SpelPostFilter.class);

	@Override
	public FlowResult doInvoke(FlowInvocation invocation) {

		String paramStr = splitXKH(invocation.statement());

		FlowResult result = invocation.invoker().invoke(invocation);

		if (result.actionResult().signal().equals(Signal.CONTINUE)) {

			if (!StringUtils.isEmpty(paramStr)) {
				try {
					try {
						log.info("流程【{}】节点【{}】SpelPost解析表达式【{}】", invocation.flowVolume().flow(),
								invocation.action().action(), paramStr);
						FlowSpelUtil.spelGetData(invocation.action(), paramStr);
					} catch (SpelEvaluationException e) {
						log.error("流程【{}】节点【{}】SpelPost解析表达式【{}】失败", invocation.flowVolume().flow(),
								invocation.action().action(), paramStr, e);
						if (e.getCause() != null && e.getCause() instanceof InvocationTargetException) {
							InvocationTargetException ie = (InvocationTargetException) e.getCause();
							if (ie.getTargetException() != null
									&& ie.getTargetException() instanceof BusicenException) {
								throw (BusicenException) ie.getTargetException();
							}
						}
						throw e;
					}
				} catch (Exception e) {
					ActionResult actionResult = ActionResult.create();
					actionResult.signal(Signal.EXCPT);
					actionResult.excpt(e);
					actionResult.action(invocation.action().action());
					actionResult.msg(invocation.action().msg());
					actionResult.data(null);
					FlowResultImpl flowResultImpl = new FlowResultImpl();
					flowResultImpl.setActionResult(actionResult);
					flowResultImpl.setException(e);
					return flowResultImpl;
				}

			} else {
				invocation.dataVolume().ext().put("EXIT", result.actionResult().data());
				log.info("流程【{}】节点【{}】SpelPost将结果放置到EXIT", invocation.flowVolume().flow(),
						invocation.action().action());
			}
		}
		return result;
	}

	@Override
	public String fileterName() {
		return "spelpost";
	}

}
